/*
+--------------------------------------------------------------------------
|   Mblog [#RELEASE_VERSION#]
|   ========================================
|   Copyright (c) 2014, 2015 mtons. All Rights Reserved
|   http://www.mtons.com
|
+---------------------------------------------------------------------------
*/
package mblog.base.analysis.videos.support;

import com.alibaba.fastjson.JSON;
import mblog.base.analysis.videos.VideoStrategy;
import mblog.base.context.AppContext;
import mblog.base.data.Video;
import mblog.base.lang.SiteConfig;
import mblog.base.utils.HttpUtils;
import mblog.base.utils.MD5Utils;
import mblog.base.vcode.ProcessingPictureResponse;
import mblog.base.vcode.RecognizeCode;
import mtons.modules.exception.MtonsException;
import mtons.modules.security.MD5;
import org.jsoup.Connection;
import org.jsoup.Jsoup;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

import java.io.IOException;
import java.util.Date;
import java.util.HashMap;
import java.util.Map;

/**
 * 搜狐视频信息抓取
 *
 * @author langhsu
 */
public class SouHu implements VideoStrategy {
    private Logger logger = LoggerFactory.getLogger(SouHu.class);

    private AppContext appContext;

    private String source = "搜狐";
    private Map<String, String> cookies = new HashMap<>();

    public SouHu(AppContext appContext) {
        this.appContext = appContext;
    }

    @Override
    public Video take(String url) {
        Video ret = null;
        try {
            String bid = loadBid(url);
            if (!bid.matches("^[0-9]*$")) {
                throw new MtonsException("地址格式不对, 或不支持该连接地址");
            }
            String videoCode = loadVideoCode(bid);
            String playerCode = loadPlayCode(bid, videoCode);
            Map map = loadVideoDetail(bid);
            ret = buildVideo(url, bid, videoCode, playerCode, map);
        } catch (Exception e) {
            throw new MtonsException("该地址请求失败");
        }
        return ret;
    }

    private Video buildVideo(String url, String bid, String videoCode, String playerCode, Map map) {
        Video ret;
        ret = new Video();
        ret.setSource(source);
        ret.setId(bid);
        ret.setTitle((String) map.get("video_name"));
        ret.setLink(url);
        ret.setThumbnail((String) map.get("hor_big_pic"));
        ret.setBigThumbnail((String) map.get("hor_big_pic"));
        ret.setBody(playerCode);
        ret.setCode(videoCode);
        ret.setDescription((String) map.get("video_desc"));
        return ret;
    }

    private Map loadVideoDetail(String bid) {
        try {
            String api_key = appContext.getConfig().get(SiteConfig.SOUHU_API_KEY);
            String url = "http://open.mb.hd.sohu.com/v4/video/info/" + bid + ".json?api_key=" + api_key + "&site=2";
            String body = HttpUtils.get(url);
            return (Map) ((Map) JSON.parse(body)).get("data");
        } catch (IOException e) {
            e.printStackTrace();
        }
        return null;
    }

    private String loadPlayCode(String bid, String videoCode) {
        return "<div id=\"videoplayer\" class='player'></div> <script>document.getElementById(\"videoplayer\").innerHTML = createSHPlayer({bid: " + bid + ",autoplay: true, vars:{\"enforceHTML5\": true},  width: \"100%\", height: \"100%\", getHTML: true, showCtrlBar: 0, channelSrc: 11510001, lqd :16542, lcode:\"" + videoCode + "\"});</script>";
    }

    private String loadVideoCode(String bid) {
        try {
            Connection.Response response = requestVideoCode(bid);

            Map map = (Map) JSON.parse(response.body());
            String code = (String) map.get("code");
            if (((Integer) map.get("status")) != 1 || code.length() > 60) {
                throw new RuntimeException("获取该视频的code失败！");
            }
            return code;
        } catch (IOException e) {
            e.printStackTrace();
            throw new RuntimeException("获取该视频的code失败！");
        }
    }

    private Connection.Response requestVideoCode(String bid) throws IOException {
        Connection.Response response = Jsoup.connect("http://lm.tv.sohu.com/promotion/gen_h5_sdk_lcode.do?bid=" + bid + "&cid=16542").followRedirects(false).timeout(10000).cookies(cookies).execute();
        if (response.statusCode() == 302) {
            int tryAmount = 0;
            String account = appContext.getConfig().get(SiteConfig.SOUHU_ACCOUNT);
            String password = MD5Utils.generate(appContext.getConfig().get(SiteConfig.SOUHU_PASSWORD)).toLowerCase();
            boolean loginSuccess = login(account, password);
            while (tryAmount < 3 && !loginSuccess) {
                loginSuccess = login(account, password);
                tryAmount++;
            }
            if (tryAmount >= 3 || !loginSuccess) {
                throw new RuntimeException("登录搜狐失败！");
            }
            response = requestVideoCode(bid);
        }
        return response;
    }

    private String loadBid(String url) {
//        url = "http://my.tv.sohu.com/us/223909021/84026953.shtml";
        return url.substring(url.lastIndexOf("/") + 1, url.lastIndexOf("."));
    }


    private boolean login(String account, String password) {
        try {
            //1.请求登录页面 http://lm.tv.sohu.com/user/tologin.do, 获取返回的cookies
            Connection.Response res = Jsoup.connect("http://lm.tv.sohu.com/user/tologin.do").execute();
            cookies.putAll(res.cookies());

            //2.请求获取验证码地址 http://lm.tv.sohu.com/verification/pic.do?t=1465092114312，更新cookies
            Connection.Response image = Jsoup.connect("http://lm.tv.sohu.com/verification/pic.do?t=" + new Date().getTime())
                    .cookies(cookies)
                    .ignoreContentType(true)
                    .execute();
            cookies.putAll(image.cookies());

            String cyAccount = appContext.getConfig().get(SiteConfig.CY_ACCOUNT);
            String cyPassword = appContext.getConfig().get(SiteConfig.CY_PASSWORD);
            //3.识别验证码
            String softId = appContext.getConfig().get(SiteConfig.CY_SOFT_ID);
            String codeType = appContext.getConfig().get(SiteConfig.CY_CODE_TYPE);
            String body = RecognizeCode.postPic(cyAccount, cyPassword, softId, codeType, "0", "0", "识别验证码", image.bodyAsBytes());
            ProcessingPictureResponse pictureResponse = JSON.parseObject(body, ProcessingPictureResponse.class);
            logger.info("识别验证码返回的数据：{}", pictureResponse);

            //4.登录Get http://lm.tv.sohu.com/user/login.do?username=qwewefwef&password=b26986ceee60f744534aaab928cc12df&vcode=9vxt
            Connection.Response loginResponse = Jsoup.connect("http://lm.tv.sohu.com/user/login.do?" +
                    "username=" + account +
                    "&password=" + password +
                    "&vcode=" + pictureResponse.getPic_str())
                    .cookies(cookies)
                    .execute();
            cookies.putAll(loginResponse.cookies());

            logger.info("登录搜狐返回的数据：{}", loginResponse.body());
            Map loginMap = (Map) JSON.parse(loginResponse.body());
            if (loginMap != null && (Integer) loginMap.get("status") != 1) {
                logger.error("验证码识别失败：{}", body);
//                RecognizeCode.reportError(cyAccount, cyPassword, softId, pictureResponse.getPic_id());
                return false;
            }
        } catch (IOException e) {
            e.printStackTrace();
        }
        return true;
    }


    public static void main(String[] args) throws IOException {
//        new SouHu().login("SilentWu", "1bea8d2288429307b8f12b9b03ec9273");
//        System.out.println("AAAAEnn7LdV6l2pJSWXwf4bqPtiyIvPKvMWgUQ..sk5".length());
//        System.out.println(JSON.parse("{\"status\":1,\"activeStatus\":1,\"username\":\"16542\"}"));
//        String bid = "34234";
//        Map<String, String> cookies = new HashMap<>();
//        cookies.put("JSESSIONID", "aaapvbrdghH9g-u8GRFuv");
//        cookies.put("IPLOC","CN5101");
//        cookies.put("SUV","1606051923205477");
//        cookies.put("UNION_KEY", "wx95IelzOApxirufrDQp6cWkl67OdM7Kz7jpQ8I792rnDwzdbDqyXg==");
//        cookies.put("Hm_lvt_3659a4e1f6285a668d9c019f83fb917c","1465125798");
//        cookies.put("Hm_lpvt_3659a4e1f6285a668d9c019f83fb917c","1465125822");
//
//        Connection.Response response = Jsoup.connect("http://lm.tv.sohu.com/promotion/gen_h5_sdk_lcode.do?bid=" + bid + "&cid=16542").followRedirects(false).timeout(10000).cookies(cookies).execute();
//        System.out.println(response.body());

//        System.out.println("n232134".matches("^[0-9]*$"));

    }


}
